#include<iostream>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<vector>
#include<ctime>
#include"tack.hpp"
#include<sys/wait.h>
//写一个进程池；
#define N 5
std::vector<void(*)()>taskv;
class PipeChanel
{
public:
    PipeChanel(int writefd,int childPid)
    :_writefd(writefd)
    ,_childPid(childPid)
    {
    }
    int getWritefd()const
    {
        return _writefd;
    }
    int getChildPid()const
    {
        return _childPid;
    }
private:
    int _writefd;
    int _childPid;
};
void work(int fd)
{
        // std::cout<<"pid:"<<getpid()<<"fd:"<<fd<<std::endl;
    while(1)
    {
        int ret;
        int n = read(fd,&ret,sizeof(ret));
        if(n>0&&n<=sizeof(ret))
        {
            std::cout<<"pid:"<<getpid()<<"fd"<<fd<<" ";
            taskv[ret]();
        
        }
        else if(n == 0)
        {
            std::cout<<"procese qiut\n";
            break;
        }
    }
    
}
void Menu()
{
    std::cout<<"#############################"<<std::endl;
    std::cout<<"1.game  2. basktaball  3.ADD"<<std::endl;
    std::cout<<"4.slepp   0.exit"<<std::endl;
}
void IniteProcese(std::vector<PipeChanel>*chanel)
{
    for(int i = 0;i<N;i++)
    {
        
        int pipearr[2]={0};
        int piperet = pipe(pipearr);
        if(piperet < 0)
        {
            std::cout<<"创建匿名管道失败\n"<<std::endl;
            perror("pipe");
            break;
        }
        pid_t id = fork();
        if(id < 0)
        {
            break;
        }
        else if(id == 0)
        {
            //child;
            close(pipearr[1]);
            work(pipearr[0]);
            exit(0);
        }
        close(pipearr[0]);
        chanel->push_back({pipearr[1],id});
    }

}

void taskCom(const std::vector<PipeChanel>&chanel)
{
    while(1)
    {
        int select = 0;
        int task = 0;
        Menu();
        std::cout<<"parent send message@:";
        std::cin>>select;
        select -= 1;
        // int ret = rand()%chanel.size();
        // int task = rand()%taskv.size();
        // int n = write(chanel[ret].getWritefd(),&task,sizeof(task));
        write(chanel[task++].getWritefd(),&select,sizeof(select));
        task %= chanel.size();
        sleep(1);
    }
}
void Debug(const std::vector<PipeChanel>&chanel)
{
    for(auto &e:chanel)
    {
         std::cout<<"pid:"<<e.getChildPid()<<"fd:"<<e.getWritefd()<<std::endl;
    }
}
void Quit(const std::vector<PipeChanel>&chanel)
{
    for(auto&e:chanel)
    {
        close(e.getWritefd());
    }
    for(auto&e:chanel)
    {
        waitpid(e.getChildPid(),NULL,0);
    }
    std::cout<<"qiut \n";
}

int main()
{



    arrangTask(&taskv);
    srand((unsigned)time(nullptr));
    std::vector<PipeChanel>chanels;
    IniteProcese(&chanels);
    taskCom(chanels);
    Quit(chanels);
    // Debug(chanels);
    return 0;
}